/* eslint-disable @typescript-eslint/no-explicit-any */
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
import { openBook } from './cmd/openBook';
import { closeDatabase, openDatabase } from './db';
import Database from 'better-sqlite3';
import { filesize } from './filesize.js';

class Catagory extends vscode.TreeItem {
	public type = 'catagory';
	constructor(public label: string, public books: number) {
		super(label, vscode.TreeItemCollapsibleState.Collapsed);
		this.id = label;
		this.description = books + '';
		this.iconPath = vscode.ThemeIcon.Folder;
	}
}

class Book extends vscode.TreeItem {
	public type = 'book';
	constructor(public id: string, public path: string, public name: string, public size: number, public author: string) {
		super(`${name} - ${author}`, vscode.TreeItemCollapsibleState.None);
		this.iconPath = vscode.ThemeIcon.File;
	}
	async loadInfo() {
		// const { filesize } = await import('filesize');
		this.tooltip = `${this.label} - ${this.author}(${filesize(this.size)})`;
		this.description = filesize(this.size) + '';
		this.command = {
			title: 'open',
			command: 'e-reader.open',
			arguments: [this.path, this.label],
		};
		return this;
	}
}

type Item = Catagory | Book;

function isBook(item: any): item is Book {
	return item && item.type === 'book';
}

function isCatagory(item: any): item is Catagory {
	return item && item.type === 'catagory';
}

class BookListProvider implements vscode.TreeDataProvider<Item> {
	private _onDidChangeTreeData: vscode.EventEmitter<Item | undefined | null | void> = new vscode.EventEmitter<
		Item | undefined | null | void
	>();
	readonly onDidChangeTreeData: vscode.Event<Item | undefined | null | void> = this._onDidChangeTreeData.event;

	refresh(): void {
		this._onDidChangeTreeData.fire();
	}

	constructor() {}
	getTreeItem(element: Item): vscode.TreeItem | Thenable<vscode.TreeItem> {
		if (isBook(element)) {
			return element.loadInfo();
		} else {
			return element;
		}
	}
	getChildren(element?: Item | undefined): Item[] {
		if (!element) {
			const list = db
				.prepare('select l.value label, count(0) num  from tb_book b, json_each(book_label) l group by l.value')
				.all();
			if (list.length === 0) {
				vscode.window.showInformationMessage('图书数据库是空的，请把有效的 book.db 文件放到 Documents 目录下！');
			}
			// const list = await this.db.queryList('select l.value label, count(0) num  from tb_book b, json_each(book_label) l group by l.value');
			return list.map((item: any) => new Catagory(item.label, item.num));
		} else {
			if (isCatagory(element)) {
				const list = db
					.prepare('select b.* from tb_book b, json_each(book_label) l where l.value = ?')
					.all(element.label);
				return list.map(
					(item: any) =>
						new Book(element.id + '/' + item.id + '', item.id, item.book_name, item.file_size, item.book_author)
				);
			} else {
				return [];
			}
		}
	}
}

let db: Database.Database;

export function activate(context: vscode.ExtensionContext) {
	db = openDatabase();

	const disposable = vscode.commands.registerCommand('e-reader.open', openBook);
	context.subscriptions.push(disposable);

	const provider = new BookListProvider();
	vscode.window.createTreeView('e-reader.bookList', {
		treeDataProvider: provider,
	});
	vscode.commands.registerCommand('e-reader.bookList.refreshEntry', () => provider.refresh());
}

export function deactivate() {
	closeDatabase();
	console.log('extension "e-reader" is now deactived!');
}
